package kevin.hbase.monitor;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.master.RegionState;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;

/**
* @author:FengZhen
* @create:2018年9月12日
*/
public class ClusterStatusTest {
 
	private static String addr="HDP233,HDP232,HDP231";
	private static String port="2181";
	private static Connection connection;
	
	public static void getConnection(){
		/*Configuration conf = HBaseConfiguration.create();
 
		conf.set("hbase.zookeeper.quorum",addr);
		conf.set("hbase.zookeeper.property.clientPort", port);*/

		Configuration config = new Configuration();
		config.addResource(new Path("conf/hbase-site.xml"));
		config = HBaseConfiguration.create(config);
		try {
			connection = ConnectionFactory.createConnection(config);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/*
	 * 关闭连接
	 */
	public static void close() {
		/**
		 * close connection
		 **/
		if (connection != null) {
			try {
				connection.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		getConnection();
		try {
			Admin admin = connection.getAdmin();
			ClusterStatus clusterStatus = admin.getClusterStatus();
			//当前活着的region服务器的数量，此数量不包括不可用region服务器
			int serversSize = clusterStatus.getServersSize();
			System.out.println("当前可用region服务器数量: " + serversSize);
			
			//当前存活的region服务器的列表,包括region服务器的服务、IP、RPC端口、启动时间戳等
			Collection<ServerName> servers = clusterStatus.getServers();
			for (ServerName serverName : servers) {
				String serverNameStr = serverName.getServerName();
				String hostAndPort = serverName.getHostAndPort();
				int port = serverName.getPort();
				Long startCode = serverName.getStartcode();
				System.out.println("serverName: " + serverNameStr + ", hostAndPort: " + hostAndPort + ", port: " + port + ", startCode: " + startCode);
			}
			
			int deadServersSize = clusterStatus.getDeadServers();
			System.out.println("当前不可用region服务器数量: " + deadServersSize);
			
			Collection<ServerName> deadServerNames = clusterStatus.getDeadServerNames();
			for (ServerName deadServerName : deadServerNames) {
				String serverNameStr = deadServerName.getServerName();
				String hostAndPort = deadServerName.getHostAndPort();
				int port = deadServerName.getPort();
				Long startCode = deadServerName.getStartcode();
				System.out.println("serverName: " + serverNameStr + ", hostAndPort: " + hostAndPort + ", port: " + port + ", startCode: " + startCode);
			}
			
			//平均每台region服务器上线了多少region
			double averageLoad = clusterStatus.getAverageLoad();
			System.out.println("平均每台region服务器上线了多少region：" + averageLoad);
			
			//集群中region的总数量
			int regionsCount = clusterStatus.getRegionsCount();
			System.out.println("集群中region的总数量: " + regionsCount);
			
			//集群的请求TPS(一个表达系统处理能力的性能指标，每秒处理的消息数（Transaction Per Second）)
			int requestsCount = clusterStatus.getRequestsCount();
			System.out.println("集群的请求TPS: " + requestsCount);
			
			//当前集群的软件编译版本 1.1.2.2.6.1.0-129
			String version = clusterStatus.getHBaseVersion();
			System.out.println("当前集群的软件编译版本: " + version);
			
			//返回集群的唯一标识。这个值是集群第一次启动时通过UUID生成的，存在根目录下的hbase.id中
			String clusterId = clusterStatus.getClusterId();
			System.out.println("集群id: " + clusterId);
			
			//返回当前集群正在进行处理的region的事务列表，即移动操作、上线操作和下线操作。
			//键是编码后的region名(由HRegTonInfo.getEncodeName返回)，值是RegionState的实例
			Map<String, RegionState> regionsInTransition = clusterStatus.getRegionsInTransition();
			
			System.out.println(">>>>>>>>>>>>>>>>>>>>>>>ServerLoad<<<<<<<<<<<<<<<<<<<<<");
			for (ServerName serverName : servers) {
				System.out.println("-------------------" + serverName.getHostAndPort() + "--------------------");
				//返回给定region服务器的当前负载情况
				ServerLoad serverLoad = clusterStatus.getLoad(serverName);
				//等同于getNumverOfRegions
				int getLoad = serverLoad.getLoad();
				System.out.println("当前region服务器上线的region数量getLoad: " + getLoad);
				//当前region服务器上线的region数量
				int getNumverOfRegions = serverLoad.getLoad();
				System.out.println("当前region服务器上线的region数量getNumverOfRegions: " + getNumverOfRegions);
				//返回当前region服务器这个周期内的TPS，周期可以通过参数hbase.reigonserver.msginterval来设定。
				//请求数会在一个周期结束后清零，它会统计所有的API请求，如get、put、increment、delete等
				long getNumberOfRequests = serverLoad.getNumberOfRequests();
				System.out.println("当前region服务器这个周期内的TPS: " + getNumberOfRequests);
				//JVM已使用的内存，单位为MB
				int getUsedHeapMB = serverLoad.getUsedHeapMB();
				System.out.println("JVM已使用的内存: " + getUsedHeapMB);
				//JVM最大可使用内存，单位为MB
				int getMaxHeapMB = serverLoad.getMaxHeapMB();
				System.out.println("JVM最大可使用内存: " + getMaxHeapMB);
				//当前region服务器的存储文件数量，即包括这个服务器管理的所有region
				int getStorefiles = serverLoad.getStorefiles();
				System.out.println("当前region服务器的存储文件数量: " + getStorefiles);
				//当前region服务器的存储文件的总存储量，单位为MB
				int getStorefileSizeInMB = serverLoad.getStorefileSizeInMB();
				System.out.println("当前region服务器的存储文件的总存储量: " + getStorefileSizeInMB);
				//当前region服务器的存储文件的索引大小，单位为MB
				int getStorefileIndexSizeInMB = serverLoad.getStorefileIndexSizeInMB();
				System.out.println("当前region服务器的存储文件的索引大小: " + getStorefileIndexSizeInMB);
				//当前region服务器的已用写缓存的大小，包括这个region服务器上所有的region
				int getMemstoreSizeInMB = serverLoad.getMemstoreSizeInMB();
				System.out.println("当前region服务器的已用写缓存的大小: " + getMemstoreSizeInMB);
				System.out.println("<<<<<<<<<<<<<<<<RegionLoad>>>>>>>>>>>>>>>>");
				//返回当前region服务器中每个region的负载情况，以Map的形式返回
				//键是region名，值是RegionLoad实例
				Map<byte[], RegionLoad> getRegionsLoad = serverLoad.getRegionsLoad();
				for (Entry<byte[], RegionLoad> value : getRegionsLoad.entrySet()) {
					String key = Bytes.toString(value.getKey());
					System.out.println("<<<<<<<<<<<<<<<<RegionLoad-" + key + ">>>>>>>>>>>>>>>>");
					RegionLoad regionLoad = value.getValue();
					//将二进制region名转换为字符串并返回
					String regionName = regionLoad.getNameAsString();
					System.out.println("regionName: " + regionName);
					//当前region的列族数量
					int getStores = regionLoad.getStores();
					System.out.println("当前region的列族数量: " + getStores);
					//当前region的存储文件数量
					int regionGetStorefiles = regionLoad.getStorefiles();
					System.out.println("当前region的存储文件数量: " + regionGetStorefiles);
					//当前region的存储文件占用空间，MB为单位
					int getStorefileSizeMB = regionLoad.getStorefileSizeMB();
					System.out.println("当前region的存储文件占用空间: " + getStorefileSizeMB);
					//当前region的存储文件的索引信息的大小，MB为单位
					int getStorefileIndexSizeMB = regionLoad.getStorefileIndexSizeMB();
					System.out.println("当前region的存储文件的索引信息的大小: " + getStorefileIndexSizeMB);
					//当前region使用的MemStore的大小，单位为MB
					int getMemStoreSizeMB = regionLoad.getMemStoreSizeMB();
					System.out.println("当前region使用的MemStore的大小: " + getMemStoreSizeMB);
					//当前region的本次统计周期内的TPS
					long getRequestsCount = regionLoad.getRequestsCount();
					System.out.println("当前region的本次统计周期内的TPS: " + getRequestsCount);
					//当前region的本次统计周期内的QPS(每秒查询率QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。)
					long getReadRequestsCount = regionLoad.getReadRequestsCount();
					System.out.println("当前region的本次统计周期内的QPS: " + getReadRequestsCount);
					//当前region的本次统计周期内的WPS
					long getWriteRequestsCount = regionLoad.getWriteRequestsCount();
					System.out.println("当前region的本次统计周期内的WPS: " + getWriteRequestsCount);
				}
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		close();
	}
	
}